home *** CD-ROM | disk | FTP | other *** search
- IF NOT lasm
- .printx * CPXPCW.ASM *
- ENDIF ;NOT lasm
- ;
- ; KERMIT - (Celtic for "FREE")
- ;
- ; This is the CP/M-80 implementation of the Columbia University
- ; KERMIT file transfer protocol.
- ;
- ; Version 4.08
- ;
- ; Copyright June 1981,1982,1983,1984,1985
- ; Columbia University
- ;
- ; Originally written by Bill Catchings of the Columbia University Center for
- ; Computing Activities, 612 W. 115th St., New York, NY 10025.
- ;
- ; This file contains the system-dependent code and data for KERMIT
- ; on the Amstrad range of personal computers.
- ;
- ;
- ; Revision history:
- ;
- ;edit 9, 22-Jan-1991 by MF. Added "sysinit" code at "init04" from Kermit
- ; version 4.08 which had been left out of version 4.09 to reserve
- ; space for the Amstrad's I/O buffers. Amstrad Kermit now stores
- ; files correctly (version 4.09 had garbled files). Again,
- ; this fix comes from Mr. D. P. Arnot of the Scottish Agricultural
- ; College in the UK.
- ;edit 8, 16-Jan-1991 by MF. Added a "bs" left out of "delstr" per
- ; instruction from David P. Arnot of Scottish Agricultural
- ; College, Auchincruive, Ayr, UK.
- ; E-mail: <D.P.Arnot@edinburgh.ac.uk>
- ; edit 7, 22 July 1987 by OBSchou to massage code to fit with CPXCOM.ASM
- ; Had to rename bcnout to bcnot as the former label clashed with
- ; one of the same name in CPXCOM.ASM. Sorry, folks.
- ;
- ; edit 6, 14th July, 1987 by OBSchou for Phillip Wade, Hull University
- ; Computer Centre. Change to delchr routine for PCW machines,
- ; as character 127 decimal is a printing character on
- ; the Amstrad PCW. The routine has been replaced
- ; by a bs,space,bs,bs string. (OBS Comment - why a total of THREE bs?)
- ;
- ; edit 5 9 May 1987 by C.J.MILES@UK.AC.UMRCC
- ; Hangup phone and clear screen options added to
- ; terminal mode.
- ;
- ; edit 4 23 March 1987 by C.J.MILES@UK.AC.UMRCC
- ; Use direct input drom SIO for CPC machines instead
- ; of using BDOS. Improvement reduces time for file
- ; transfer to 65% of time used by BDOS method.
- ; Add reverse Prestel baud rate.
- ;
- ; edit 3 20 March 1987 by Chris Miles (C.J.MILES@UK.AC.UMRCC)
- ; (Greater Manchester Archaeological Unit, Manchester Univ.).
- ; Added support for Amstrad CPC CP/M Plus machines,
- ; Added 31250 baud rate option,
- ; Bug fixed in sending BREAK,
- ; Bug fixed in 1200/75 baud setup
- ; Machine and CP/M version checks added.
- ;
- ; edit 2 11 Febuary, 1987 by OBSchou for Ian Young.
- ; Changes to the send break routine to change two lines of code from
- ; ori 018h ; send break, Tx enable
- ; and ori 0008h ; Tx enable
- ;
- ; to ori 01ah ; send break, Tx enable, RTS
- ; and ori 00ah ; Tx enable, RTS
- ;
- ; This is a bug fix to hopefully keep RTS actve during breaks.
- ;
- ; [Ed. (OBSchou) 21/1/87.
- ; This file linked FROM cpxsys.asm, so do NOT rename this
- ; file. The diffculty of needing a HUGE CPXSYS.ASM file on your floppy
- ; only to act as a switcher remains, but hopefully will be better in
- ; the future. If you ARE stuck, then rename this CPXSYS.ASM but add the
- ; label SYSEDT: to the FAMILY label. A bit messy.]
- ;
- ;
- ; The "author" of this system-dependent file is:
- ;
- ; Ian A. Young
- ; Lattice Logic Ltd
- ; 9 Wemyss Place
- ; Edinburgh
- ;
- ; Some other addresses:
- ;
- ; ian@latlog.uucp
- ; ...seismo!mcvax!ukc!latlog!ian
- ; or c/o OBSchou@uk.ac.lut.multics
- ;
- ; ... although much of the code concerned was written by others.
- ;
-
-
- ; Keep module name, edit number, and last revision date in memory.
-
- ;sysedt: db 'CPXSYS.ASM (36) 20-Mar-87$'
- family: db 'CPXPCW.ASM (9) 22-Jan-1991$'
-
-
- ;
- ; Assembly-time message announcing which version we are building
- ;
-
- IF pcw
- .printx * Assembling Amstrad PCW Kermit-80 *
- ENDIF
-
- IF cpc
- .printx * Assembling Amstrad CPC Kermit-80 *
- ENDIF
-
- ;
- ; Miscellany of parameter settings
- ;
- z80 EQU TRUE ; all Amstrads have a Z80.
- defesc EQU '\'-100O ; The default escape character.
- vtval EQU 0 ; we don't need VT52 emulation
-
- ;
- ; Amstrad CPC machines use 16 bit I/O address decoding and therefore
- ; the Z80 instructions OUT (C),A and IN A,(C) must be defined.
- ;
- outc EQU 79edh ; IN A,(C)
- inpc EQU 78edh ; OUT (C),A
-
- ;
- ; hardware information
- ;
- ; There is a Z80-DART (Mostek/SGS 8470) at I/O addresses E0..E3 (PCW)
- ; and FADC..FADD (CPC), and a 8253 programmable divider running it at
- ; E4..E7 (PCW) and FBDC..FBDF (CPC)
- ;
-
- input EQU 01h ; input data available
- output EQU 04h ; output buffer ready
-
- IF pcw
- mnport EQU 0E0h ; data register for SIO
- mnprts EQU 0E1h ; control register for SIO
- ctc0 EQU 0E4h ; 8253 load counter 0
- ctc1 EQU 0E5h ; 8253 load counter 1
- ctcmod EQU 0E7h ; 8253 write mode word
- ENDIF
-
- IF cpc
- mnport EQU 0FADCh ; data register for SIO
- mnprts EQU 0FADDh ; control register for SIO
- ctc0 EQU 0FBDCh ; 8253 load counter 0
- ctc1 EQU 0FBDDh ; 8253 load counter 1
- ctcmod EQU 0FBDFh ; 8253 write mode word
- ENDIF
-
- ;
- ; SIO input buffering
- ;
- siosz EQU 4096 ; size of SIO input buffer
- siomsk EQU 4095 ; mask for wrapping buffer round
-
- ;
- ; Extended BIOS jump-block addresses; reached through USERF
- ;
- sainit EQU 00B6h ; initialise SIO
- sabaud EQU 00B9h ; set baud rate
- saparm EQU 00BCh ; fetch SIO parameters
- teask EQU 00BFh ; find out cursor position
- cdvers EQU 00E3h ; get version numbers
- cdinfo EQU 00E6h ; get BIOS system information
-
- ;
- ; System-dependent initialization
- ; Called once at program start.
- sysxin: ; continuation of system initialzation
- ;
- ; check for correct CP/M version
- ;
- mvi c,12 ; get CP/M version BDOS call
- call bdos
- mov a,l ; check if CP/M Plus
- cpi 31h
- jz init08
- lxi d,wrong2 ; point to error message
- call prtstr
- mvi c,0 ; warm boot
- call bdos
- ;
- init08: ;[OBS] Moved the Cinfigured for message out as
- ;[OBS] it is in CPXCOM.ASM
- ;
- ; get addresses of BIOS routines
- ;
- ; BIOS USERF is used to get to extended BIOS routines
- ;
- lhld 1 ; warm boot vector
- lxi d,87 ; offset to USERF vector
- dad d ; DE now has USERF vector address
- shld userf+1 ; ready for jumping to...
- ;
- ; BIOS routines for fast character I/O
- ;
- lhld 1 ; warm boot vector (#1)
- lxi d,3
- dad d ; next is #2, CONST
- shld bcnst+1
- dad d ; next is #3, CONIN
- shld bcnin+1
- dad d ; next is #4, CONOUT
- shld bcnot+1 ;[obs] Was bcnout, but this conflicts
- ;[obs] with a label in CPXCOM.ASM
- dad d ; next is #5, LIST
- shld blist+1
- dad d ; next is #6, AUXOUT
- dad d ; next is #7, AUXIN
- shld baxin+1
- lhld 1 ; warm boot vector again
- lxi d,002Ah ; offset to LISTST (#15)
- dad d
- shld lptstat+1
- lhld 1 ; warm boot vector again
- lxi d,0033h ; offset to AUXIST (#18)
- dad d
- shld baxist+1
- ;
- ; check if running on correct Amstrad
- ;
- call userf
- dw cdvers
- IF pcw
- cpi 0
- ENDIF
- IF cpc
- cpi 1
- ENDIF
- jnz init06
- lxi d,wrong1 ; point to error message
- call prtstr
- mvi c,0
- call bdos
- ;
- ; verify presence of SIO board by asking the BIOS.
- ;
- init06: call userf ; C gets 00 if not fitted
- dw cdinfo
- xra a ; a <- 0
- ora c ; zero => no serial port
- jnz init03 ; non-zero => OK
- lxi d,nosio ; snooty message...
- call prtstr
- mvi c,0 ; warm boot out of here
- call bdos
- init03:
- ;
- ; find initial baud rate and other information
- ;
- call userf ; gives B=rx baud, C=tx baud, D=stop bits,
- ; E=parity, H=rx bits, L=tx bits.
- dw saparm ; get SIO parameters
- push h ; save bit settings
- mov a,b ; if TX and RX speeds same, they are OK
- cmp c
- jz init01
- cpi 8 ; rx=1200?
- jnz init02 ; no, can't be Prestel
- mov a,c
- cpi 2 ; tx=75?
- jnz init02 ; no, can't be Prestel
- lxi b,0 ; otherwise 1200/75 comes out as 0s.
- init01: push b ; assign value to SPEED
- pop h
- shld speed
- init02: ; here if we leave it as is
- pop h ; get bit settings
- mov a,l ; no of TX data bits set
- sui 5 ; make into 00, 01, 10, 11.
- rrc
- rrc
- rrc
- sta txbits ; we may need it later
- ;
- ; set handshake mode: there are two parts to this, interrupts and
- ; hardware handshake. The MODE byte used by the firmware expresses
- ; this combination as -(int*2 + hand*1). Thus, both options on would
- ; be (-3) or 0FDh.
- ;
- ; Here, we set the interrupt part of the mode on; it helps the BIOS cope.
- ; Unfortunately, >sigh<, according to Soft971, this will only work
- ; if you have BIOS V1.4 or higher. I have no idea what would happen
- ; if we tried random hanshake mode flags with lower versions, so we
- ; just skip over if it would be dangerous...
- ;
- call userf ; fetch all parameters
- dw saparm
- sta orgmode ; remember original mode for later
-
- call userf ; get BIOS version to B,C
- dw cdvers
- mov a,b ; BIOS major version number (eg 1)
- ora a ; if zero, too low...
- jz init04
- cpi 1 ; if not 1, definitely OK
- jnz init05
- mov a,c ; otherwise, its 1.X; want >= 4
- cpi 4
- jm init04 ; <4 => too low
-
- init05: call userf ; get the original flags back
- dw saparm
- xri 0FFh ; make mode into bit mask
- inr a
- ori 2 ; set interrupt mode
- xri 0FFh ; turn back into mode value
- inr a
- call userf ; feed change back to BIOS
- dw sainit
- init04: ; come here if not setting mode
-
- ; Locate large buffers for multi-sector I/O and SIO input buffering.
- ; Space above ovlend is available for buffers; we have pretty well the machine
- ; to ourselves in an Amstrad PCW because they all gave 61K TPAs. We don't even
- ; bother to perform any checking.
- ; We don't want to use more than maxsec for disk buffers because
- ; if we use too many, the remote end could time out while we're
- ; writing to disk. maxsec is system-dependent, but for now we'll just
- ; use 8Kbytes. If you get retransmissions and other protocol errors after
- ; transferring the first maxsec sectors, lower maxsec.
- ;
- maxsec EQU (8*1024)/bufsiz ; 8K / number of bytes per sector
-
- lxi h,ovlend+siosz ; get start of buffer
- shld bufadr ; store in linkage section
- mvi a,maxsec ; get size of buffer, in sectors
- sta bufsec ; store that, too.
-
-
- ret ; return from system-dependent routine
-
- ;
- ; message complaining about wrong Amstrad machine
- ;
- wrong1: db 'Error - This Kermit will only run on the Amstrad '
- IF pcw
- db 'PCW 8256/8512'
- ENDIF
- IF cpc
- db 'CPC 464/664/6128'
- ENDIF
- db cr,lf,'$'
- ;
- ; message complaining about version of CP/M being used
- ;
- wrong2: db 'Error - Incorrect CP/M version, needs CP/M 3.x'
- db cr,lf,'$'
- ;
- ; message complaining of no SIO board
- ;
- nosio: db 'Error - No SIO option fitted to this machine'
- db cr, lf, '$'
-
- ;
- ; jumps to BIOS character I/O routines.
- ; Addresses filled in by initialisation code above.
- ;
- bcnst: jmp $-$ ; console status
- bcnin: jmp $-$ ; console input
- bcnot: jmp $-$ ; console output [obs - was bcnout]
- blist: jmp $-$ ; printer output
- baxin: jmp $-$ ; aux port input
- baxist: jmp $-$ ; aux port status
- lptstat:jmp $-$ ; printer status
-
- ;
- ; Other BIOS routines
- ;
- userf: jmp $-$ ; call extended BIOS function
-
- ;
- ; saved value of some original parameters
- ;
- orgmode:ds 1
- txbits: ds 1
-
- ;
- ; system-dependent termination processing
- ; If we've changed anything, this is our last chance to put it back.
- sysexit:
- call userf ; fetch firmware parameters
- dw saparm
- lda orgmode ; replace with original mode
- call userf ; inform BIOS
- dw sainit
- ret
-
- ;
- ; system-dependent processing for start of CONNECT command
- ;
- syscon:
- lxi d,conmsg ; how to get escape char message
- call prtstr
- ret
-
- conmsg: ; Messages printed when entering transparent (CONNECT) mode:
- IF pcw
- db '(Use boxed minus key next to space bar to generate a Control-\)'
- ENDIF
- db cr,lf,'$'
-
- ;
- ; syscls - system-dependent close routine
- ; called when exiting transparent session.
- ;
- syscls:
- ret
-
- ;
- ; sysinh - help for system-dependent special functions.
- ; called in response to <escape>?, after listing all the
- ; system-independent escape sequences.
- ;
- sysinh:
- lxi d,inhlps ; we got options...
- call prtstr ; print them.
- ret
-
- ;
- ; additional, system-dependent help for transparent mode
- ; (two-character escape sequences)
- ;
- inhlps:
- db cr,lf,'B Transmit a BREAK'
- db cr,lf,'H Hangup using DTR'
- db cr,lf,'W Wipe screen clear'
- db '$' ;[hh] table terminator
-
- ;
- ; sysint - system dependent special functions
- ; called when transparent escape character has been typed;
- ; the second character of the sequence is in A (and in B).
- ; returns:
- ; non-skip: sequence has been processed
- ; skip : sequence was not recognized
- ;
- sysint: ani 137O ; convert lower case to upper, for testing...
- cpi 'B' ; send break ?
- jz sendbr ; yes, go do it. return nonskip when through.
- cpi 'H' ; hang up ?
- jz hangup
- cpi 'W' ; clear screen ?
- jz clrtop
- jmp rskp ; take skip return - command not recognized.
-
- ;
- ; Hangup (drop DTR) and Break send routine
- ;
-
- hangup:
- mvi d,0ah ; set up hangup bit mask
- mvi e,255 ; time for hangup is 2 1/2 secs
- jmp setbit ; skip Tx empty test
-
- sendbr:
- mvi d,9ah ; set up break bit mask
- mvi e,30 ; time for break is 300 ms
-
- sndbr1: mvi a,1 ; select Read Register 1
-
- IF pcw ; allow 8 bit I/O instructions
- out mnprts
- in mnprts ; read the contents
- ENDIF
-
- IF cpc ; use 16 bit I/O instructions
- lxi b,mnprts
- dw outc ; OUT (C),A
- dw inpc ; IN A,(C)
- ENDIF
-
- ani 1 ; test "all done" flag
- jz sndbr1 ; loop until it's nonzero.
- ;
- ; Next, set the break or hangup bit on the SIO.
- ;
- setbit:
- mvi a,5 ; select Write Register 5
- IF pcw
- out mnprts
- ENDIF
- IF cpc
- dw outc ; OUT (C),A
- ENDIF
- lda txbits ; get txbits (already in correct bit positions)
- ora d ; send break, Tx Enable, RTS
- IF pcw
- out mnprts
- ENDIF
- IF cpc
- dw outc ; OUT (C),A
- ENDIF
-
- ;
- ; Now, delay for duration of hangup or break
- ;
- mov a,e ; delay count
- call delay
- ;
- ; Time's up. Put transmitter back in normal state and return.
- ;
- mvi a,5 ; select Write Register 5
- IF pcw
- out mnprts
- ENDIF
- IF cpc
- lxi b,mnprts
- dw outc ; OUT (C),A
- ENDIF
- lda txbits ; get txbits again
- ori 8ah ; Reset break, Tx Enable, RTS
- IF pcw
- out mnprts
- ENDIF
- IF cpc
- dw outc ; OUT (C),A
- ENDIF
- ret ; done.
-
- ;
- ; sysflt - system-dependent filter
- ; called with character in E.
- ; if this character should not be printed, return with A = zero.
- ; preserves bc, de, hl.
- ; note: <xon>,<xoff>,<del>, and <nul> are always discarded.
- ;
- sysflt:
- mov a,e ; get character for testing
- ret
- ;
- ; system-dependent processing for BYE command.
- ;
- sysbye:
- ret
-
- ;
- ; This is the system-dependent command to change the baud rate.
- ; DE contains the two-byte value from the baud rate table; this
- ; value is also stored in 'speed'.
- ;
- sysspd:
- push d ; move to HL for firmware
- pop h
- mov a,h ; if h=0 then Prestel rates
- ora a
- jnz spd01 ; if not 1200/75 then skip
- lxi h,0802H ; else set 1200/75 into HL
- jmp spd03 ; jump to normal setup
-
- spd01: cpi 11h ; if h=11h then reverse Prestel
- jnz spd02 ; if not 75/1200 then skip
- lxi h,0208h ; else set 75/1200 into HL
- jmp spd03 ; jump to normal setup
-
- spd02: cpi 10h ; if h=10h then 31250 baud
- jnz spd03 ; if not 31250 then skip to normal setup
- mvi a,36h ; set 8253 for mode 2 binary count
- lxi b,ctcmod ; output to CTC mode register
- dw outc
- lxi b,ctc0 ; select transmit clock
- mov a,4 ; timer value for 31250 (04h)
- dw outc
- mov a,0 ; timer value for 31250 (04h)
- dw outc
- lxi b,ctc0 ; select receive clock
- mov a,4 ; timer value for 31250 (04h)
- dw outc
- mov a,0 ; timer value for 31250 (04h)
- dw outc
- ret
-
- spd03: call userf ; set whatever we have now...
- dw sabaud ; using BIOS routine
- ret
-
- ;
- ; Speed tables
- ; (Note that speed tables MUST be in alphabetical order for later
- ; lookup procedures, and must begin with a value showing the total
- ; number of entries. The speed help tables are just for us poor
- ; humans.
- ;
- ; db string length,string,divisor (2 identical bytes or 1 word)
- ;
- spdtbl: db 12h ;18 entries
- db 03h,'110$', 03h,03h
- db 04h,'1200$', 08h,08h
- db 07h,'1200/75$', 00h,00h ; real values faked up when required
- db 05h,'134.5$', 04h,04h
- db 03h,'150$', 05h,05h
- db 04h,'1800$', 09h,09h
- db 05h,'19200$', 0fh,0fh
- db 04h,'2400$', 0ah,0ah
- db 03h,'300$', 06h,06h
- db 05h,'31250$',10h,10h ; flag to direct setup routine
- db 04h,'3600$', 0bh,0bh
- db 04h,'4800$', 0ch,0ch
- db 02h,'50$', 01h,01h
- db 03h,'600$', 07h,07h
- db 04h,'7200$', 0dh,0dh
- db 02h,'75$', 02h,02h
- db 07h,'75/1200$',11h,11h ; real values faked up when required
- db 04h,'9600$', 0eh,0eh
-
- sphtbl: db cr,lf,lf
- db 'Normal rates: 50 75 110 134.5 150 300 600'
- db cr,lf
- db ' 1200 1800 2400 3600 4800 7200 9600 19200'
- db cr,lf,lf
- db 'High speed : 31250 (only between Amstrads)'
- db cr,lf,lf
- db 'Split rates : 1200/75 (Rx=1200, Tx= 75)'
- db cr,lf
- db ' 75/1200 (Rx= 75, Tx=1200)'
- db cr,lf,'$'
-
- ;
- ; This is the system-dependent SET PORT command.
- ; HL contains the argument from the command table.
- ;
- sysprt:
- ret
-
- prttbl equ 0 ; SET PORT is not supported
- prhtbl equ 0
-
- ;
- ; selmdm - select modem port
- ; selcon - select console port
- ; selmdm is called before using inpmdm or outmdm;
- ; selcon is called before using inpcon or outcon.
- ; preserves bc, de, hl.
- ;
- selmdm:
- selcon:
- ret
-
- ;
- ; Get character from console, or return zero.
- ; result is returned in A. destroys bc, de, hl.
- ;
- inpcon:
- call bcnst ; get console status
- ora a ; anything there?
- rz ; no, forget it
- jmp bcnin ; yes, get the character
-
- ;
- ; Output character in E to the console.
- ; destroys bc, de, hl
- ;
- outcon:
- mov a,e ; TAB?
- cpi tab
- jz out001
- mov c,e ; set correct arg register
- jmp bcnot ; output to console via BIOS [obs was bcnout]
-
- ;
- ; perform tab expansion ourselves
- ;
- out001: call userf ; get column in L
- dw teask
- mov a,l ; a <- column 0..n
- ani 7 ; column 0..7
- xri 0FFh ; not(col 0..7)
- adi 9 ; a is 8-(colf7)
- out002: ora a ; any left?
- rz ; return if not
- dcr a ; one less now, anyhow
- push psw ; save over BIOS call (just in case)
- mvi c,' ' ; print one space
- call bcnot ;[obs was bcnout]
- call suck ; in case any stuff coming in
- pop psw ; fetch count back
- jmp out002 ; and go round again
-
- ;
- ; outmdm - output a char from E to the modem.
- ; the parity bit has been set as necessary.
- ; returns nonskip; bc, de, hl preserved.
- outmdm:
- IF cpc
- push b ; save BC for CPC 16 bit I/O
- ENDIF
- outmd1:
- call xsuck ; keep checking for incoming characters
- IF pcw
- in mnprts ; get the output done flag.
- ENDIF
- IF cpc
- lxi b,mnprts
- dw inpc ; IN A,(C)
- ENDIF
- ani output ; is it set?
- jz outmd1 ; if not, loop until it is.
- mov a,e
- IF pcw
- out mnport ; output it.
- ENDIF
- IF cpc
- lxi b,mnport
- dw outc ; OUT (C),A
- pop b ; restore BC
- ENDIF
- ret
-
- ;
- ; get character from modem; return zero if none available.
- ; destroys bc, de, hl.
- ;
- inpmdm:
- call suck ; get any characters pending
- lhld sioct ; count of chars in buffer
- mov a,h ; or together to get result
- ora l
- rz ; not got any, return now
-
- dcx h ; down count
- shld sioct
-
- lhld siord ; read pointer
- mov c,m ; fetch character ** NB TO C FOR NOW **
-
- lxi d,1-ovlend ; bump pointer, subtract base
- dad d
- mov a,h ; mask high byte of offset
- ani siomsk/256
- mov h,a
- lxi d,ovlend ; add in base again
- dad d
- shld siord
-
- mov a,c ; get to proper register
- ret
-
- ;
- ; flsmdm - flush comm line.
- ; Modem is selected.
- ; Currently, just gets characters until none are available.
-
- flsmdm: call inpmdm ; Try to get a character
- ora a ; Got one?
- jnz flsmdm ; If so, try for another
- ret ; Receiver is drained. Return.
-
- ;
- ; SIO input buffer handling. The buffer pointers are held as pointers into
- ; the buffer. The read pointer
- ; is to the next unused character, the write pointer to the next unused space.
- ;
- siord: dw ovlend ; next char to read
- siowr: dw ovlend ; next char to write
- sioct: dw 0 ; number in buffer
-
- xsuck: push d ; save regs version of suck
- push b
- push h
- call suck
- pop h
- pop b
- pop d
- ret
-
- ;
- ; suck
- ;
- ; this routine is called whenever it would be possible that some
- ; characters might be available in the SIO device; they are all
- ; transferred (there may be up to 4 pending) to the buffer.
- ;
- ; all registers are destroyed
- ;
- suck:
- IF pcw
- call baxist ; check input status via BDOS
- ora a ; check if zero
- ENDIF
- IF cpc
- lxi b,mnprts ; get input status directly
- dw inpc ; IN A,(C)
- ani input ; mask for Rx ready
- ENDIF
- rz ; return if no
-
- IF pcw
- call baxin ; fetch character via BDOS
- ENDIF
- IF cpc
- lxi b,mnport ; fetch character directly from SIO
- dw inpc ; IN A,(C)
- ENDIF
-
- lhld siowr ; write pointer
- mov m,a ; put character
-
- lxi d,1-ovlend ; take off base, bump pointer
- dad d
- mov a,h ; top byte of offset
- ani siomsk/256 ; masked off
- mov h,a
- lxi d,ovlend ; add on base again
- dad d
- shld siowr ; replace pointer
-
- lhld sioct ; bump count in buffer
- inx h
- shld sioct
-
- jmp suck ; go round in case any more
-
- ;
- ; outlpt - output character in E to printer
- ; console is selected.
- ; preserves de.
- outlpt:
- push d ; save DE in either case
- mov c,e ; correct arg register
- call blist
- pop d ; restore saved register pair
- ret
-
- ;
- ; Screen manipulation routines
- ; csrpos - move to row B, column C
- ;
- ; csrpos for terminals that use a leadin sequence followed
- ; by (row + 31.) and (column + 31.)
- ; or (row) and (column)
- ;
- csrpos: push b ; save coordinates
- lxi d,curldn ; get cursor leadin sequence
- call prtstr ; print it
- pop h ; restore coordinates
- mov a,h ; get row
- adi (' '-1) ; space is row one
- mov e,a
- push h
- call outcon ; output row
- pop h
- mov a,l ; get column
- adi (' '-1) ; space is column one
- mov e,a
- jmp outcon ; output it and return
-
- ;
- ; delchr - make delete look like a backspace. Unless delete is a printing
- ; character, we just need to print a backspace. (we'll output clrspc
- ; afterwards)
- ; For Kaypro and Vector General, delete puts a blotch on the screen.
- ; For Apple and Osborne 1, delete moves but doesn't print.
- delchr:
- IF pcw ;[6] OBS for Phillip Wade
- lxi d,delstr ;[5] send a string rather than a single character
- call prtstr
-
- delstr: db bs,' ',bs,'$' ;[OBS] Was bs,space,bs,bs
- ENDIF ;pcw
-
- mvi e,bs ;get a backspace
- jmp outcon
-
- ; erase the character at the current cursor position
- clrspc: mvi e,' '
- call outcon
- mvi e,bs ;get a backspace
- jmp outcon
-
- ; erase the current line
- clrlin: lxi d,eralin
- jmp prtstr
-
- ; erase the whole screen, and go home. preserves b (but not c)
- clrtop: lxi d,erascr
- jmp prtstr
-
-
- IF pcw
- sysver: db 'Amstrad PCW with SIO option$'
- ENDIF
- IF cpc
- sysver: db 'Amstrad CPC with CP/M Plus$'
- ENDIF
-
- outlin: db esc,'H',esc,'J',cr,lf,' $'
-
- erascr: db esc,'H',esc,'J$' ;Clear screen and go home.
- eralin: db cr,esc,'K$' ;Clear line.
- curldn: db esc,'Y$' ;cursor leadin
- ttab: ;Table start location.
- ta: db esc,'A$',0 ;Cursor up.
- tb: db esc,'B$',0 ;Cursor down.
- tc: db esc,'C$',0 ;Cursor right.
- td: db esc,'D$',0 ;Cursor left
- te: db esc,'E$',0 ;Clear display
- tf: db '$',0,0,0 ;Enter Graphics Mode
- tg: db '$',0,0,0 ;Exit Graphics mode
- th: db esc,'H$',0 ;Cursor home.
- ti: db esc,'I$',0 ;Reverse linefeed.
- tj: db esc,'J$',0 ;Clear to end of screen.
- tk: db esc,'K$',0 ;Clear to end of line.
-
- ovlend equ $ ; End of overlay
-
- END
-